#include "comm/my_atomic.h"
#include "comm/my_log.h"

void test_atomic_int64()
{
    my_atomic_int64_t a = 0;
    my_atomic_int64_reset(&a);

    if (my_atomic_int64_load(&a) != 0) {
        MY_LOG_FATAL("except 0, but got other");
    }

    if (my_atomic_int64_cas(&a, 1, 2)) {
        MY_LOG_FATAL("except false, but got true");
    }

    if (my_atomic_int64_fetch_add(&a, 1) != 0) {
        MY_LOG_FATAL("except 0, but got other");
    }

    if (my_atomic_int64_add_fetch(&a, 1) != 2) {
        MY_LOG_FATAL("except 2, but got other");
    }
    
    if (!my_atomic_int64_cas(&a, 2, 10)) {
        MY_LOG_FATAL("except true, but got false");
    }

    if (my_atomic_int64_load(&a) != 10) {
        MY_LOG_FATAL("except 10, but got other");
    }
}

void test_atomic_bool()
{
    my_atomic_bool_t b = 0;
    my_atomic_bool_reset(&b);

    if (my_atomic_bool_is_true(&b)) {
        MY_LOG_FATAL("except false, but got true");
    }

    my_atomic_bool_set_true(&b);
    if (!my_atomic_bool_is_true(&b)) {
        MY_LOG_FATAL("except true, but got false");
    }

    my_atomic_bool_set_false(&b);
    if (my_atomic_bool_is_true(&b)) {
        MY_LOG_FATAL("except false, but got true");
    }
}

void test_atomic_ptr()
{
    my_atomic_ptr_t p = 0;
    my_atomic_ptr_reset(&p);

    if (my_atomic_ptr_load(&p) != NULL) {
        MY_LOG_FATAL("except NULL, but got other");
    }

    if (my_atomic_ptr_swap(&p, (void *)1) != NULL) {
        MY_LOG_FATAL("except NULL, but got other");
    }

    if (!my_atomic_ptr_cas(&p, (void *)1, (void *)2)) {
        MY_LOG_FATAL("except true, but got false");
    }

    if (my_atomic_ptr_cas(&p, (void *)1, (void *)3)) {
        MY_LOG_FATAL("except false, but got true");
    }

    if (my_atomic_ptr_load(&p) != (void *)2) {
        MY_LOG_FATAL("except 0x2, but got other");
    }
}

int main()
{
    test_atomic_int64();
    test_atomic_bool();
    test_atomic_ptr();

    MY_LOG_DEBUG("test pass");
}